package com.zhentao.controller;

import com.zhentao.config.RedisChatMemory;
import com.zhentao.dto.*;
import com.zhentao.service.AiConversationService;
import com.zhentao.service.AiMessageService;
import com.zhentao.service.CustomerServiceTransferService;
import com.zhentao.tools.MyTools;
import io.jsonwebtoken.io.IOException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.content.Media;
import org.springframework.ai.image.ImageModel;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@RestController
//@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS})
public class AIChatClient {
    @Autowired
    private ChatClient myChatClient;

    @Autowired
    private MyTools myTools;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private AiConversationService conversationService;

    @Autowired
    private AiMessageService messageService;

    @Autowired
    private RedisChatMemory redisChatMemory;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private CustomerServiceTransferService customerServiceTransferService;

    @GetMapping(value = "/ai/chat", produces = "text/html;charset=utf-8")
    public Flux<String> chat(@RequestParam String question,
                             @RequestParam(required = false) String memoryId,
                             @RequestParam(required = false) Integer userId)
    {
        // 参数验证
        if (question == null || question.trim().isEmpty()) {
            return Flux.just("请输入有效的问题内容");
        }

        try {
            // 如果提供了用户ID但没有会话ID，尝试创建或获取默认会话
            String  conversationId = memoryId;
            if (userId != null && (conversationId == null || conversationId.trim().isEmpty())) {
                conversationId = getOrCreateDefaultConversation(userId);
            }

            // 记录用户消息到数据库
            if (userId != null && conversationId != null) {
                try {
                    messageService.saveUserMessage(userId, conversationId, question.trim());
                    conversationService.updateLastMessage(conversationId, question.trim());
                } catch (Exception e) {
                    System.err.println("保存用户消息失败: " + e.getMessage());
                }
            }

            String finalConversationId1 = conversationId;

            // 设置工具调用的上下文信息
            com.zhentao.tools.MyTools.setCurrentContext(userId, finalConversationId1);

            ChatClient.StreamResponseSpec stream = myChatClient
                    .prompt()
                    .tools(myTools)
                    .advisors( // 使用 Advisor
                            advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, finalConversationId1)
                    )
                    .user(question.trim())
                    .stream();
            Flux<String> content = stream.content();
            System.out.println("用户消息: " + question);
            System.out.println("会话ID: " + conversationId);
            System.out.println("用户ID: " + userId);

            // 收集AI回复并保存到数据库
            StringBuilder sb = new StringBuilder();
            final String finalConversationId = conversationId;
            content = content.doOnNext(s -> sb.append(s))
                    .doOnComplete(() -> {
                        String aiResponse = sb.toString();
                        System.out.println("AI回复: " + aiResponse);

                        // 保存AI回复到数据库
                        if (userId != null && finalConversationId != null && !aiResponse.trim().isEmpty()) {
                            try {
                                messageService.saveAssistantMessage(userId, finalConversationId,
                                    aiResponse.trim(), "qwen-plus", null);
                                conversationService.updateLastMessage(finalConversationId, aiResponse.trim());
                            } catch (Exception e) {
                                System.err.println("保存AI回复失败: " + e.getMessage());
                            }
                        }

                        // 清除工具调用的上下文信息
                        com.zhentao.tools.MyTools.clearCurrentContext();
                    })
                    .doOnError(error -> {
                        // 发生错误时也要清除上下文
                        com.zhentao.tools.MyTools.clearCurrentContext();
                    });

            return content;
        } catch (Exception e) {
            System.err.println("AI对话处理异常: " + e.getMessage());
            e.printStackTrace();
            return Flux.just("抱歉，AI服务暂时不可用，请稍后重试。");
        }
    }





    private final ImageModel imageModel;

    public AIChatClient(ImageModel imageModel) {
        this.imageModel = imageModel;
    }

    @GetMapping("/image")
    @SneakyThrows
    public void image(HttpServletResponse response, @RequestParam(required = false) String message) {

        ImageResponse imageResponse = imageModel.call(new ImagePrompt(message));
        String imageUrl = imageResponse.getResult().getOutput().getUrl();
        System.out.println("Image URL: " + imageUrl);
        try {
            URL url = URI.create(imageUrl).toURL();
            InputStream in = url.openStream();

            response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
            response.getOutputStream().write(in.readAllBytes());
            response.getOutputStream().flush();
        } catch (IOException | java.io.IOException e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    // ==================== AI会话管理接口 ====================

    /**
     * 创建新的AI会话
     */
    @PostMapping("/ai/conversation")
    public ResponseEntity<Map<String, Object>> createConversation(@Valid @RequestBody CreateConversationRequest request) {
        try {
            AiConversationDTO conversation = conversationService.createConversation(request);

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "会话创建成功");
            response.put("data", conversation);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "创建会话失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 获取用户的会话列表
     */
    @GetMapping("/ai/conversations")
    public ResponseEntity<Map<String, Object>> getUserConversations(
            @RequestParam Integer userId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "false") boolean includeArchived) {
        try {
            Page<AiConversationDTO> conversations = conversationService
                .getUserConversations(userId, page, size, includeArchived);

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", conversations.getContent());
            response.put("totalElements", conversations.getTotalElements());
            response.put("totalPages", conversations.getTotalPages());
            response.put("currentPage", page);
            response.put("pageSize", size);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "获取会话列表失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 获取会话详情
     */
    @GetMapping("/ai/conversation/{conversationId}")
    public ResponseEntity<Map<String, Object>> getConversation(
            @PathVariable String conversationId,
            @RequestParam Integer userId) {
        try {
            return conversationService.getConversationById(userId, conversationId)
                .map(conversation -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", true);
                    response.put("data", conversation);
                    return ResponseEntity.ok(response);
                })
                .orElseGet(() -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", false);
                    response.put("message", "会话不存在");
                    return ResponseEntity.notFound().build();
                });
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "获取会话详情失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 获取会话的聊天历史
     */
    @GetMapping("/ai/conversation/{conversationId}/history")
    public ResponseEntity<Map<String, Object>> getChatHistory(
            @PathVariable String conversationId,
            @RequestParam Integer userId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "false") boolean descending) {
        try {
            ChatHistoryRequest request = new ChatHistoryRequest();
            request.setUserId(userId);
            request.setConversationId(conversationId);
            request.setPage(page);
            request.setSize(size);
            request.setDescending(descending);

            Page<AiMessageDTO> messages = messageService.getChatHistory(request);

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", messages.getContent());
            response.put("totalElements", messages.getTotalElements());
            response.put("totalPages", messages.getTotalPages());
            response.put("currentPage", page);
            response.put("pageSize", size);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "获取聊天历史失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 更新会话标题
     */
    @PutMapping("/ai/conversation/{conversationId}/title")
    public ResponseEntity<Map<String, Object>> updateConversationTitle(
            @PathVariable String conversationId,
            @RequestParam Integer userId,
            @RequestParam String title) {
        try {
            boolean success = conversationService.updateConversationTitle(userId, conversationId, title);

            Map<String, Object> response = new HashMap<>();
            if (success) {
                response.put("success", true);
                response.put("message", "会话标题更新成功");
            } else {
                response.put("success", false);
                response.put("message", "会话不存在或更新失败");
            }

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "更新会话标题失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 删除会话
     */
    @DeleteMapping("/ai/conversation/{conversationId}")
    public ResponseEntity<Map<String, Object>> deleteConversation(
            @PathVariable String conversationId,
            @RequestParam Integer userId) {
        try {
            boolean success = conversationService.deleteConversation(userId, conversationId);

            Map<String, Object> response = new HashMap<>();
            if (success) {
                response.put("success", true);
                response.put("message", "会话删除成功");
            } else {
                response.put("success", false);
                response.put("message", "会话不存在或删除失败");
            }

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "删除会话失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 归档会话
     */
    @PutMapping("/ai/conversation/{conversationId}/archive")
    public ResponseEntity<Map<String, Object>> archiveConversation(
            @PathVariable String conversationId,
            @RequestParam Integer userId) {
        try {
            boolean success = conversationService.archiveConversation(userId, conversationId);

            Map<String, Object> response = new HashMap<>();
            if (success) {
                response.put("success", true);
                response.put("message", "会话归档成功");
            } else {
                response.put("success", false);
                response.put("message", "会话不存在或归档失败");
            }

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "归档会话失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 置顶/取消置顶会话
     */
    @PutMapping("/ai/conversation/{conversationId}/pin")
    public ResponseEntity<Map<String, Object>> togglePinConversation(
            @PathVariable String conversationId,
            @RequestParam Integer userId) {
        try {
            boolean success = conversationService.togglePinConversation(userId, conversationId);

            Map<String, Object> response = new HashMap<>();
            if (success) {
                response.put("success", true);
                response.put("message", "会话置顶状态更新成功");
            } else {
                response.put("success", false);
                response.put("message", "会话不存在或更新失败");
            }

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "更新会话置顶状态失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 搜索会话
     */
    @GetMapping("/ai/conversations/search")
    public ResponseEntity<Map<String, Object>> searchConversations(
            @RequestParam Integer userId,
            @RequestParam String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size) {
        try {
            Page<AiConversationDTO> conversations = conversationService
                .searchConversations(userId, keyword, page, size);

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", conversations.getContent());
            response.put("totalElements", conversations.getTotalElements());
            response.put("totalPages", conversations.getTotalPages());
            response.put("currentPage", page);
            response.put("pageSize", size);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "搜索会话失败: " + e.getMessage());

            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 获取或创建用户的默认会话
     */
    private String getOrCreateDefaultConversation(Integer userId) {
        try {
            // 尝试获取用户最近的活跃会话
            Page<AiConversationDTO> conversations = conversationService
                .getUserConversations(userId, 1, 1, false);

            if (!conversations.isEmpty()) {
                return conversations.getContent().get(0).getConversationId();
            }

            // 如果没有现有会话，创建一个新的默认会话
            CreateConversationRequest request = new CreateConversationRequest();
            request.setUserId(userId);
            request.setTitle("默认对话");

            AiConversationDTO newConversation = conversationService.createConversation(request);
            return newConversation.getConversationId();

        } catch (Exception e) {
            System.err.println("获取或创建默认会话失败: " + e.getMessage());
            // 返回一个临时会话ID
            return "temp_" + userId + "_" + System.currentTimeMillis();
        }
    }

    // ==================== 系统健康检查接口 ====================

    /**
     * 健康检查接口
     */
    @GetMapping("/ai/health")
    public ResponseEntity<Map<String, Object>> healthCheck() {
        Map<String, Object> health = new HashMap<>();

        try {
            // 检查MongoDB连接
            boolean mongoHealthy = checkMongoHealth();

            // 检查Redis连接
            boolean redisHealthy = checkRedisHealth();

            // 检查AI服务
            boolean aiHealthy = checkAiServiceHealth();

            health.put("timestamp", System.currentTimeMillis());
            health.put("status", (mongoHealthy && redisHealthy && aiHealthy) ? "UP" : "DOWN");
            health.put("components", Map.of(
                "mongodb", mongoHealthy ? "UP" : "DOWN",
                "redis", redisHealthy ? "UP" : "DOWN",
                "ai-service", aiHealthy ? "UP" : "DOWN"
            ));

            return ResponseEntity.ok(health);
        } catch (Exception e) {
            health.put("timestamp", System.currentTimeMillis());
            health.put("status", "DOWN");
            health.put("error", e.getMessage());

            return ResponseEntity.status(503).body(health);
        }
    }

    /**
     * 检查MongoDB健康状态
     */
    private boolean checkMongoHealth() {
        try {
            mongoTemplate.getCollection("ai_conversations").countDocuments();
            return true;
        } catch (Exception e) {
            System.err.println("MongoDB健康检查失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 检查Redis健康状态
     */
    private boolean checkRedisHealth() {
        try {
            // 简单的ping测试
            String testKey = "health_check_" + System.currentTimeMillis();
            redisTemplate.opsForValue().set(testKey, "test", 1, java.util.concurrent.TimeUnit.SECONDS);
            String value = (String) redisTemplate.opsForValue().get(testKey);
            return "test".equals(value);
        } catch (Exception e) {
            System.err.println("Redis健康检查失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 检查AI服务健康状态
     */
    private boolean checkAiServiceHealth() {
        try {
            // 发送一个简单的测试请求
            ChatClient.StreamResponseSpec stream = myChatClient
                .prompt()
                .user("健康检查")
                .stream();

            // 检查是否能正常获取响应
            return stream != null;
        } catch (Exception e) {
            System.err.println("AI服务健康检查失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 获取系统统计信息
     */
    @GetMapping("/ai/stats")
    public ResponseEntity<Map<String, Object>> getSystemStats() {
        try {
            Map<String, Object> stats = new HashMap<>();

            // 获取会话统计
            long totalConversations = mongoTemplate.getCollection("ai_conversations").countDocuments();
            long activeConversations = mongoTemplate.getCollection("ai_conversations")
                .countDocuments(new org.bson.Document("status", "ACTIVE"));

            // 获取消息统计
            long totalMessages = mongoTemplate.getCollection("ai_messages").countDocuments();

            // 获取今日统计
            java.time.LocalDateTime todayStart = java.time.LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
            long todayMessages = mongoTemplate.getCollection("ai_messages")
                .countDocuments(new org.bson.Document("timestamp",
                    new org.bson.Document("$gte", todayStart)));

            stats.put("totalConversations", totalConversations);
            stats.put("activeConversations", activeConversations);
            stats.put("totalMessages", totalMessages);
            stats.put("todayMessages", todayMessages);
            stats.put("timestamp", System.currentTimeMillis());

            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "获取统计信息失败: " + e.getMessage());
            return ResponseEntity.status(500).body(error);
        }
    }

    // ==================== 客服转人工接口 ====================

    /**
     * 手动转人工接口
     */
    @PostMapping("/ai/transfer-to-human")
    public ResponseEntity<Map<String, Object>> transferToHuman(@RequestBody Map<String, Object> request) {
        try {
            Integer userId = (Integer) request.get("userId");
            String conversationId = (String) request.get("conversationId");
            String message = (String) request.get("message");

            if (userId == null) {
                Map<String, Object> error = new HashMap<>();
                error.put("success", false);
                error.put("message", "用户ID不能为空");
                return ResponseEntity.badRequest().body(error);
            }

            Map<String, Object> result = customerServiceTransferService.handleTransferToHuman(
                userId, conversationId, message != null ? message : "用户请求转人工"
            );

            return ResponseEntity.ok(result);
        } catch (Exception e) {
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("message", "转人工失败: " + e.getMessage());
            return ResponseEntity.status(500).body(error);
        }
    }

    /**
     * 获取客服统计信息
     */
    @GetMapping("/ai/customer-service/stats")
    public ResponseEntity<Map<String, Object>> getCustomerServiceStats() {
        try {
            Map<String, Object> stats = customerServiceTransferService.getCustomerServiceStats();
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            Map<String, Object> error = new HashMap<>();
            error.put("error", "获取客服统计信息失败: " + e.getMessage());
            return ResponseEntity.status(500).body(error);
        }
    }

}
